﻿using System;
using System.Collections.Generic;
using System.IO.Ports;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 串口转发
{
    public struct ComPortAttr
    {
        public int Baudrate;
        public int Databit;
        public Parity Parity;
        public StopBits Stopbit;
        public string ComportName;
    }
    public class UartStateEventArgs:EventArgs
    {
        public string datas;

    }

    public delegate void UartReceivedEventHandler(UartStateEventArgs e);
        
    public class UartServer
    {
        private SerialPort serialPort;
        public event UartReceivedEventHandler UartReceived;

        private bool IsRunning = false;
        private bool IsStoped = false;
        private Queue<byte[]> _DatasQueue = new Queue<byte[]>();
        private Queue<string> _SendQueue = new Queue<string>();

        private int total;


        public UartServer(ComPortAttr attr)
        {
            serialPort = new SerialPort();
            serialPort.PortName = attr.ComportName;
            serialPort.BaudRate = attr.Baudrate;
            serialPort.Parity = attr.Parity;
            serialPort.DataBits = attr.Databit;
            serialPort.StopBits = attr.Stopbit;
            serialPort.ReadBufferSize = 10240;
            serialPort.WriteBufferSize = 10240;

            try
            {
                serialPort.Open();

                Task.Run(() =>
                {
                    while (serialPort.IsOpen && !IsStoped)
                    {
                        IsRunning = true;
                        //UartStateEventArgs e = new UartStateEventArgs();

                        if (serialPort.BytesToRead > 0)
                        {
                            //e.datas = serialPort.ReadExisting();
                            //UartReceived?.BeginInvoke(e, null, null);

                            _SendQueue.Enqueue(serialPort.ReadExisting());
                        }
                    }
                    IsRunning = false;
                });

                Task.Run(() =>
                {
                    while (serialPort.IsOpen && !IsStoped)
                    {
                        IsRunning = true;

                        UartStateEventArgs e = new UartStateEventArgs();

                        if (_SendQueue.Count > 0)
                        {
                            e.datas = _SendQueue.Dequeue();
                            UartReceived?.Invoke(e);
                        }
                    }
                    IsRunning = false;
                });

                Task.Run(() =>
                {
                    while (serialPort.IsOpen && !IsStoped)
                    {
                        IsRunning = true;
                        if (_DatasQueue.Count > 0)
                        { 
                            byte[] datas = _DatasQueue.Dequeue();
                            if (datas != null)
                            {
                                serialPort.Write(datas, 0, datas.Length);
                            }
                        }

                    }
                    IsRunning = false;
                });

            }
            catch
            {
                serialPort.Close();
            }
        }

        public void UartTransmit(byte[] datas)
        {
            _DatasQueue.Enqueue(datas);

        }

        public void Stop()
        {
            IsStoped = true;
            while (IsRunning) ;
            serialPort.Close() ;
        }
    }
}
